package com.tuo51.evaluate.service.appuser;

import com.tuo51.evaluate.domain.appusers.*;
import com.tuo51.evaluate.domain.business.Product;
import com.tuo51.evaluate.domain.evaluatingV2.EvaluateV2Record;
import com.tuo51.core.domain.org.Organization;
import com.tuo51.core.domain.staffs.Staff;
import com.tuo51.core.repositories.OrgnizationRepository;
import com.tuo51.evaluate.repositories.appusers.*;
import com.tuo51.evaluate.repositories.evaluatev2.EvaluateV2RecordRepository;
import com.tuo51.core.service.StaffService;
import com.tuo51.foudation.constant.APPConstants;
import com.tuo51.foudation.exception.BusinessException;
import com.tuo51.foudation.model.APPErrorCode;
import com.tuo51.foudation.model.ErrorCode;
import com.tuo51.foudation.utils.DateUtil;
import com.tuo51.foudation.utils.MemberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Service
public class ProductService {


    @Autowired
    private VipRepository vipRepository;

    @Autowired
    private OrgnizationRepository orgnizationRepository;

    @Autowired
    private EvaluateV2RecordRepository recordRepository;

    @Autowired
    private PromoCodeRepository promoCodeRepository;

    @Autowired
    private RedeemCodeRepository redeemCodeRepository;

    @Autowired
    private StaffRedeemCodeRepository staffRedeemCodeRepository;


    @Autowired
    private StaffService staffService;

    public <T> T getProductById(long productId){
        return (T)vipRepository.getOne(productId);
    }


    @Transactional
    public void productReportIssue(String reportId) {
        EvaluateV2Record  report = recordRepository.getOne(reportId);
        report.setPaid(true);
        recordRepository.save(report);
    }

    /**
     * 处理订单，发放物资。
     * @param userId
     * @param product
     */
    @Transactional
    public void productVIPIssue(String userId, Vip product) {

        try {
            Staff user =  staffService.getById(userId);

            Organization org = staffService.staffOrgnization(user);

            if (Objects.nonNull(user)) {
                if (product.getType() == APPConstants.ProductType.DURATIONS.getValue()) {
                    //增加时间
                    MemberUtils.addUserVIPDuration(org, product.getValue().intValue());

                } else if (product.getType() == APPConstants.ProductType.TIMES.getValue()) {
                    //增加次数
                    MemberUtils.addUserVIPTimes(org, product.getValue().intValue());
                }
                orgnizationRepository.save(org);
            } else {
                throw new BusinessException(ErrorCode.STAFF_NOT_EXIST, "用户不存在");
            }
        } catch (Exception e) {
            e.printStackTrace();
            String message = String.format("产品发放失败:productId={},productType={},userId={}", product.getId(), product.getType(), userId);
            throw new BusinessException(APPErrorCode.PRODUCT_ISSUE_FAIL.getCode(), message, e);
        }

    }

    @Transactional(rollbackFor = BusinessException.class)
    public Object redeemCodeIssue(String staffId, String code){

        RedeemCode redeemCode = redeemCodeRepository.getByCodeAndDeletedIsFalse(code);

        if(redeemCode == null){
            throw new BusinessException(ErrorCode.REDEEMCODE_NOTFOUND, "兑换码无效");
        }

        StaffRedeemCode staffRedeemCode = staffRedeemCodeRepository.getByStaffIdAndRedeemCodeId(staffId, redeemCode.getId());
        if(staffRedeemCode != null){
            throw new BusinessException(ErrorCode.PROMOCODE_OUTCOUNT, "您已经兑换成功，不需要重复使用。");
        }

        if (redeemCode.getSalesQuota() <= redeemCode.getSalesQuantity()){
            throw new BusinessException(ErrorCode.REDEEMCODE_OUTCOUNT, "兑换码最多兑换 " + redeemCode.getSalesQuota() + " 次，剩余次数 0 。");
        }

        Vip vip = redeemCode.getProduct();

        productVIPIssue(staffId, vip);

        Staff staff = staffService.getById(staffId);

        staffRedeemCode = new StaffRedeemCode();

        Organization org = staffService.staffOrgnization(staff);

        staffRedeemCode.setComment("兑换" + vip.getName() + "成功,您当前VIP会员期限至"
                + DateUtil.parseToDateDay(org.getExpireTime())
                + ( org.getRestCount() == null ? "。" : ", 可用测评报告份数为" + org.getRestCount() + "。"));

        staffRedeemCode.setStaffId(staff.getId());
        staffRedeemCode.setProductId(vip.getId());
        staffRedeemCode.setRedeemCodeId(redeemCode.getId());

        staffRedeemCodeRepository.save(staffRedeemCode);

        //更新兑换码
        redeemCode.setSalesQuantity(redeemCode.getSalesQuantity() + 1);
        redeemCodeRepository.save(redeemCode);

        return staffRedeemCode;
    }

    public Object promoCodePreview(long productId, String code) {
        PromoCode promoCode = promoCodeRepository.getByCode(code);
        if(promoCode == null){
            throw new BusinessException(ErrorCode.PROMOCODE_NOTFOUND, "优惠码无效");
        }

        if (promoCode.getSalesQuota() <= promoCode.getSalesQuantity()){
            throw new BusinessException(ErrorCode.PROMOCODE_OUTCOUNT, "优惠码用完了");
        }

        Product product = getProductById(productId);

        Integer newPrice = product.getPrice();
        if(promoCode.getProductId() == null || promoCode.getProductId() == productId){
            newPrice = promoCode.calc(newPrice);;
        }

        Map result = new HashMap();
        result.put("code", promoCode.getCode());
        result.put("type", promoCode.getType());
        result.put("rebate", promoCode.getRebate());
        result.put("newPrice", newPrice);
        result.put("originPrice", product.getPrice());

        return result;
    }

    public Object redeemCodePreview(String code){
        RedeemCode redeemCode = redeemCodeRepository.previewCode(code);

        if(redeemCode == null){
            throw new BusinessException(ErrorCode.REDEEMCODE_NOTFOUND, "兑换码无效");
        }

        if (redeemCode.getSalesQuota() <= redeemCode.getSalesQuantity()){
            throw new BusinessException(ErrorCode.REDEEMCODE_OUTCOUNT, "兑换码用完了");
        }

        Vip vip = redeemCode.getProduct();


        return vip;

    }

}
